package client

import (
	"database/sql"
	"fmt"
	"gin-epg/internal/app/client/utils"
	"gin-epg/internal/app/dao"
	"gin-epg/internal/app/entity"
	"github.com/go-resty/resty/v2"
	"golang.org/x/net/html"
	"strings"
	"time"
)

// 节目表网页 http://sports8.cc/jintian/435/
// Sports8 频道名称映射
var mapSports8 = map[string]string{
	"126":  "湖南经视",
	"127":  "湖南都市",
	"128":  "金鹰纪实",
	"437":  "湖南爱晚",
	"435":  "湖南娱乐",
	"594":  "湖南电影",
	"436":  "湖南电视剧",
	"2933": "凤凰卫视中文台",
	"2811": "凤凰卫视资讯台",
	"1958": "凤凰卫视香港台",
	// 更多键值对...
}

// HandleSports8Cron 处理 Sports8 节目单
func HandleSports8Cron() error {
	dao.Logger.Infof("handleSports8Cron start")
	urlDate := time.Now().Format("2006-01-02")
	dao.Logger.Infof(urlDate)
	source := "sports8"

	client := resty.New()
	for key, value := range mapSports8 {
		dao.Logger.Infof("Key: %s, Value: %s", key, value)
		url := fmt.Sprintf("http://sports8.cc/jintian/%s/", key)

		resp, err := client.R().
			SetHeaders(map[string]string{
				"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
			}).
			Get(url)

		if err != nil {
			return fmt.Errorf("failed to get data from URL: %v", err)
		}

		doc, err := html.Parse(strings.NewReader(resp.String()))
		if err != nil {
			return fmt.Errorf("failed to parse HTML: %v", err)
		}

		var parseEpg func(*html.Node)
		parseEpg = func(n *html.Node) {
			if n.Type == html.ElementNode && n.Data == "div" {
				if utils.HasAttr(n, "id", "Weepgprogram_epgInfo") {
					programs := utils.ParseSports8EpgInfo(n, urlDate, value, source)
					// 填充 stop 字段
					for i := 0; i < len(programs)-1; i++ {
						programs[i].End = programs[i+1].Start
					}
					// 最后一个节目的结束时间设置为当天的最后一分钟
					if len(programs) > 0 {
						programs[len(programs)-1].End = "23:59"
					}

					// 批量插入或更新数据库
					for _, program := range programs {
						db := dao.SqlSession
						var existingRecord entity.EpgProgramCollect
						dateParsed, err := time.Parse("2006-01-02", urlDate)
						if err != nil {
							dao.Logger.Fatalf("failed to parse date: %v", err)
						}
						if err := db.Where(&entity.EpgProgramCollect{Channel: program.Channel, Date: entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}}, Start: program.Start, Source: program.Source}).First(&existingRecord).Error; err == nil {
							dao.Logger.Debugf("update success: %v", existingRecord)
							if existingRecord.Title != program.Title {
								dao.Logger.Debugf("title changed, update title")
								db.Model(&existingRecord).Updates(entity.EpgProgramCollect{Title: program.Title, Desc: "", UpdateTime: entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}}})
							}
						} else {
							dao.Logger.Debugf("insert Sports8 epgProgramCollect")
							program.CreateTime = entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}}
							if err := db.Create(&program).Error; err != nil {
								dao.Logger.Errorf("insert error: %v", err)
							} else {
								dao.Logger.Debugf("insert success: %v", program)
							}
						}
					}
				}
			}
			for c := n.FirstChild; c != nil; c = c.NextSibling {
				parseEpg(c)
			}
		}

		parseEpg(doc)
	}
	return nil
}
